package simulation;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

import creators.CenterMassCreator;
import creators.Creator;
import creators.GravityCreator;
import creators.MassCreator;
import creators.MuscleCreator;
import creators.SpringCreator;
import creators.ViscosityCreator;
import creators.WallCreator;


/**
 * contains methods for loading the simulation & environment.
 *
 * @author Robert C. Duvall
 * edited by Schwartz & Roy
 */
public class Factory {
    // data file keywords
    private static final String MASS_KEYWORD = "mass";
    private static final String SPRING_KEYWORD = "spring";
    private static final String MUSCLE_KEYWORD = "muscle";

    // contains all the creators
    private Map<String, Creator> creators;

    /**
     * constructor sets up creators.
     */
    public Factory() {
        creators = new HashMap<String, Creator>();
        initCreators();
    }

    /**
     * sets up each type of creator for the HashMap.
     */
    private void initCreators() {
        creators.put(MASS_KEYWORD, new MassCreator());
        creators.put(SPRING_KEYWORD, new SpringCreator());
        creators.put(MUSCLE_KEYWORD, new MuscleCreator());
        creators.put(Environment.GRAVITY_NAME, new GravityCreator());
        creators.put(Environment.VISCOSITY_NAME, new ViscosityCreator());
        creators.put(Environment.CENTERMASS_NAME, new CenterMassCreator());
        creators.put(Environment.WALL_NAME, new WallCreator());
    }

    /**
     * reads in Environment file and updates values accordingly
     *      in the Environment class.
     *
     * @param model is created Model
     * @param modelFile is file containing environment properties
     */
    public void loadEnvironment(Model model, File modelFile) {
        try {
            Scanner input = new Scanner(modelFile);
            while (input.hasNext()) {
                Scanner line = new Scanner(input.nextLine());
                if (line.hasNext()) {
                    String type = line.next();
                    creators.get(type).create(model, line);
                }
            }
            input.close();
        } catch (FileNotFoundException e) {
            // should not happen because File came from user selection
            e.printStackTrace();
        }
    }

    /**
     * reads in simulation file with properties of masses and springs.
     *
     * @param model is the created Model
     * @param modelFile is the simulation file
     */
    public void loadModel(Model model, File modelFile) {
        try {
            Scanner input = new Scanner(modelFile);
            while (input.hasNext()) {
                Scanner line = new Scanner(input.nextLine());
                if (line.hasNext()) {
                    String type = line.next();
                    creators.get(type).create(model, line);
                }
            }
            input.close();
        } catch (FileNotFoundException e) {
            // should not happen because File came from user selection
            e.printStackTrace();
        }
        model.finalizeLoadingMasses();
    }
}